﻿using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using Microsoft.Office.Interop.Word;

namespace DocxHelper
{
    public class DocxConverter : IDisposable
    {
        private Application _app;
        private Image _waterMark;

        public DocxConverter(string water)
        {
            _waterMark = Image.FromFile(water);
            _app = new Application
            {
                DisplayAlerts = WdAlertLevel.wdAlertsNone,
            };
        }


        public void ToImage(string docx, int maxWidth, int pages, int cut)
        {
            var doc = _app.Documents.Open(docx, ReadOnly: true, AddToRecentFiles: false, Visible: false);
            foreach (Window window in doc.Windows)
            {
                foreach (Pane pane in window.Panes)
                {
                    if (pane.Pages.Count <= 3)
                    {
                        pages = 1;
                    }

                    var fileWithoutExt = Path.Combine(Path.GetDirectoryName(docx), Path.GetFileNameWithoutExtension(docx));
                    for (var i = 1; i <= pages; i++)
                    {
                        var page = pane.Pages[i];
                        object bits = page.EnhMetaFileBits;
                        try
                        {
                            using (var ms = new MemoryStream((byte[])bits))
                            using (var image = Image.FromStream(ms))
                            {
                                using (var bitmap = ResizeImage(image, maxWidth, cut, _waterMark))
                                {
                                    var png = $"{fileWithoutExt}-{i}.png";
                                    bitmap.Save(png, ImageFormat.Png);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex.ToString());
                        }
                    }
                }
            }
            doc.Close(Type.Missing, Type.Missing, Type.Missing);
        }

        public void Dispose()
        {
            if (_app != null)
            {
                _waterMark?.Dispose();
                try
                {
                    _app.Documents.Close();
                }
                catch
                {
                    // ignore
                }
                _app.Quit();
                _app = null;
            }
        }

        private static Image ResizeImage(Image image, int width, int cut, Image water)
        {
            if (width <= 0 && cut <= 0)
            {
                return image;
            }

            var height = Convert.ToInt32(image.Height * ((double)width / image.Width));
            var destRect = new System.Drawing.Rectangle(0, 0, width, height);
            var destImage = new Bitmap(width, height);

            destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);

            using (var graphics = Graphics.FromImage(destImage))
            {
                graphics.CompositingMode = CompositingMode.SourceCopy;
                graphics.CompositingQuality = CompositingQuality.HighQuality;
                graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                graphics.SmoothingMode = SmoothingMode.HighQuality;
                graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

                using (var wrapMode = new ImageAttributes())
                {
                    wrapMode.SetWrapMode(WrapMode.TileFlipXY);
                    graphics.DrawImage(image, destRect, cut, cut, image.Width - cut, image.Height - cut, GraphicsUnit.Pixel, wrapMode);

                    if (water != null)
                    {
                        var right = width - water.Width;
                        graphics.DrawImage(water, 0, 0, water.Width, water.Height);
                        graphics.DrawImage(water, right, 0, water.Width, water.Height);

                        var mid = (height - water.Height) / 2;
                        graphics.DrawImage(water, 0, mid, water.Width, water.Height);
                        graphics.DrawImage(water, right, mid, water.Width, water.Height);

                        var bottom = height - water.Height;
                        graphics.DrawImage(water, 0, bottom, water.Width, water.Height);
                        graphics.DrawImage(water, right, bottom, water.Width, water.Height);

                    }
                }
            }

            return destImage;
        }

    }
}